/**
 * X-COM Pawn Class
 * Uses for x-com pawns
 */
class xT_Pawn_Human extends xT_Pawn;

//=============================================================================
// Special actions variables
//=============================================================================
var public int			                                EnergyMax;              //Max Energy module value for special combat actions
var public int			                                Energy;                 //Current Energy module value for special combat actions
var private float                                       EnergyRegenerationTimer, EnergyRegenerationSpeed; // Energy regeneration

var public bool                                         bInvisibilityActive;
var public bool                                         bShieldsActive;
var private float                                       EnergyDegenTimer; // Shields and invisibility degeneration

//=============================================================================
// Global variables
//=============================================================================
var private xFX_Decals_Pawn                             SelectionEffect;
var private xFX_Decals_Pawn                             StaticDecalEffect;

var private float                                       HealthRegenerationTimer, HealthRegenerationSpeed; // Health regeneration

//=============================================================================
// Functions
//=============================================================================
function PostBeginPlay()
{
	Super.PostBeginPlay();
	ShowStaticDecalEffect(); //Show static shine decal of x-com soldier
	Energy = EnergyMax;
}

/** Show static shine decal of x-com soldier **/
function ShowStaticDecalEffect()
{
	StaticDecalEffect = Spawn(class'xFX_Decals_Pawn',self,,Location);
	StaticDecalEffect.SetNewDecalMaterial("xT_Decals.Materials.Pawn_Selection_Unselected_Mat");
	StaticDecalEffect.SetBase(self);
}

/** Show shine decal of x-com soldier when this soldier is selected by the player **/
function ShowSelectionDecalEffect()
{
	SelectionEffect = Spawn(class'xFX_Decals_Pawn',self,,Location);
	SelectionEffect.SetNewDecalMaterial("xT_Decals.Materials.Pawn_Selection_Mat");
	SelectionEffect.SetBase(self);
}

/** Show shine decal when pawn is selected **/
function DoShowSelection(bool aShowSelection)
{
	if (!bIsDied)
	{
		if(!aShowSelection)
		{

			SelectionEffect.Destroy();
			SelectionEffect = none;
		}
		else if(SelectionEffect == none)
		{
			ShowSelectionDecalEffect();
		}
	}
}

/**
 * Apply a given overlay material to the overlay mesh.
 */
simulated function SetOverlayMaterial(MaterialInterface NewOverlay)
{
	local int i;

	// If we are authoritative, then set up replication of the new overlay
	if (Role == ROLE_Authority)
	{
		OverlayMaterialInstance = NewOverlay;
	}

	if (Mesh.SkeletalMesh != None)
	{
		if (NewOverlay != None)
		{
			// pawn overlay mesh
			for (i = 0; i < OverlayMesh.SkeletalMesh.Materials.Length; i++)
			{
				OverlayMesh.SetMaterial(i, OverlayMaterialInstance);
			}

			if (!OverlayMesh.bAttached)
			{
				AttachComponent(OverlayMesh);
			}
			
			//weapon overlay
			x_Weapons(self.weapon).SetOverlayMaterial(OverlayMaterialInstance);
		}
		else
		{
			if (OverlayMesh.bAttached)
			{
				DetachComponent(OverlayMesh);
			}
			if (x_Weapons(self.weapon).isOverlayAttached())
			{
				x_Weapons(self.weapon).DetachOverlayMesh();
			}
		}
	}
}

function bool Died(Controller Killer, class<DamageType> damageType, vector HitLocation)
{
	/*
	if (xT_AIController(Controller).CurrentCoverLink != none)
	{
		if (xT_AIController(Controller).CurrentCoverSlot != -1)
		{
			xT_AIController(Controller).CurrentCoverLink.UnClaim(self, xT_AIController(Controller).CurrentCoverSlot, false);
		}
	}
	*/

	`log(" function bool Died ");
	Health = 1;
	FeignDeath();
	SetTimer(WorldInfo.DeltaSeconds, true, 'GetUpAfterFeignDeath');
	return false;
}

function GetUpAfterFeignDeath()
{
	if (Health >= HealthMax/2)
	{
		`log(" ------------------ GetUpAfterFeignDeath()");
		FeignDeath();
		ClearTimer('GetUpAfterFeignDeath');
	}
}

/** This state used from xcT_Pawn but with decals destruction **/
State Dying
{
	simulated function BeginState(Name PreviousStateName)
	{
		if ((mainPlayerController != none) && bIsSelected)
		{
			mainPlayerController.SelectedUnitsRemoveUnit(self);
			if (!(mainPlayerController.IsInState('TacticsControllerState'))) 
				mainPlayerController.GotoState('TacticsControllerState');
			mainPlayerController = none;
		}
		StaticDecalEffect.Destroy();

		Super.BeginState(PreviousStateName);
	}
}

/*********************************************************************************************
Regeneration Mechanics
**********************************************************************************************/
function Tick(float DeltaTime)
{
	super.Tick(DeltaTime);

	// regen health
	if (Health < HealthMax)
	{
		if (Health <= 10){ HealthRegenerationSpeed = default.HealthRegenerationSpeed + 0.25; } else HealthRegenerationSpeed = default.HealthRegenerationSpeed;
			
		HealthRegenerationTimer += HealthRegenerationSpeed;
		if (HealthRegenerationTimer >= 1.0)
		{
			RegenerateHealth();
		}
	}

	//regen shields
	if (bShieldsActive)
	{
		if (Energy > 0)
		{
			EnergyDegenTimer += EnergyRegenerationSpeed * 2;
			if (EnergyDegenTimer >= 1.0)
			{
				DegenerateEnergy();
			}
		}
	}

	//regen invisibility
	if (bInvisibilityActive)
	{
		if (Energy > 0)
		{
			EnergyDegenTimer += EnergyRegenerationSpeed * 2;
			if (EnergyDegenTimer >= 1.0)
			{
				DegenerateEnergy();
			}
		}
	}

	// regen energy
	if (!bShieldsActive && !bInvisibilityActive)
	{
		if (Energy < EnergyMax)
		{
			EnergyRegenerationTimer += EnergyRegenerationSpeed;
			if (EnergyRegenerationTimer >= 1.0)
			{
				RegenerateEnergy();
			}
		}
	}
}

simulated function RegenerateHealth()
{
	Health++;
	HealthRegenerationTimer = 0;
}

simulated function RegenerateEnergy()
{
	Energy++;
	EnergyRegenerationTimer = 0;
}
simulated function DegenerateEnergy()
{
	Energy--;
	EnergyDegenTimer = 0;
	if (Energy <= 0)
	{
		if (bShieldsActive) DeActivateShield();
		if (bInvisibilityActive) DeActivateInvisiblity();
	}
}

//=============================================================================
// Special action
//=============================================================================
function ActivateInvisiblity()
{
	if (bShieldsActive) DeActivateShield();

	if (bInvisibilityActive)
	{
		DeActivateInvisiblity();
	}
	else
	{
		bInvisibilityActive = true;

		SetOverlayMaterial(class'x_Settings'.default.InvisibleMaterial);

		Mesh.CastShadow = false;
		Mesh.bCastDynamicShadow = false;
		Mesh.SetHidden(true);

		ReattachMesh();

		self.Weapon.bShadowParented = false;
		self.Weapon.Mesh.SetHidden(true);

		ReattachWeaponMesh();
	}
}

function DeActivateInvisiblity()
{
	bInvisibilityActive = false;
	SetOverlayMaterial(None);
	Mesh.SetHidden(false);
	self.Weapon.bShadowParented = true;
	self.Weapon.Mesh.SetHidden(false);
	UpdateShadowSettings(!class'Engine'.static.IsSplitScreen());
}

function ActivateShield()
{
	if (bInvisibilityActive) DeActivateInvisiblity();

	if (bShieldsActive)
	{
		DeActivateShield();
	}
	else
	{
		if (Energy >  class'x_Settings'.default.CostActivateShields)
		{
			bShieldsActive = true;
			SetOverlayMaterial(class'x_Settings'.default.ShieldMaterial);
		}
	}
}

function DeActivateShield()
{
	bShieldsActive = false;
	SetOverlayMaterial(None);
}

function AdjustDamage(out int InDamage, out vector Momentum, Controller InstigatedBy, vector HitLocation, class<DamageType> aDamageType, TraceHitInfo HitInfo, Actor DamageCauser)
{
	local int lpreDamage;
	if( bShieldsActive && class<xT_DamageType>(aDamageType).default.bShieldStops && (inDamage > 0) )
	{
		lpreDamage = inDamage;		
		inDamage = AbsorbDamage(inDamage, Energy, 1.0);
		if (lpreDamage >= Energy) Energy = 0;
		
	}
	super.AdjustDamage(InDamage, Momentum, InstigatedBy, HitLocation, aDamageType, HitInfo, DamageCauser);
} 

//=============================================================================
// DefaultProperties
//=============================================================================
DefaultProperties
{
	mExpForKill = 0

	Begin Object Class=PointLightComponent Name=MyLightComponent
    LightAffectsClassification=LAC_STATIC_AFFECTING
		Radius=480.0
		CastShadows=FALSE
		CastStaticShadows=FALSE
		CastDynamicShadows=FALSE
		bCastCompositeShadow=FALSE
		bAffectCompositeShadowDirection=FALSE
		bForceDynamicLight=TRUE
		UseDirectLightMap=FALSE
		LightingChannels=(BSP=TRUE,Static=TRUE,Dynamic=TRUE,bInitialized=TRUE)
		Brightness=0.25
 	End Object
	Components.Add(MyLightComponent)

	Begin Object Name=PawnSkeletalMeshComponent
		AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
		AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_AimOffset'
		AnimSets(1)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'
		//AnimSets(2)=AnimSet'xc_M_sol_MA.hum_anim'
	End Object
 
	Begin Object Class=SkeletalMeshComponent Name=OverlayMeshComponent0
		Scale=1.015
		bAcceptsDynamicDecals=FALSE
		CastShadow=false
		bOwnerNoSee=true
		bUpdateSkelWhenNotRendered=false
		bOverrideAttachmentOwnerVisibility=true
		TickGroup=TG_PostAsyncWork
		bAllowAmbientOcclusion=false
		bPerBoneMotionBlur=true
	End Object
	OverlayMesh=OverlayMeshComponent0

	AIControllerTemplateClass = class'xT_AIController_Human' //human controller
	DefaultAICommandState = ECS_Idle
	Team = ET_HUMAN

	SoundGroupClass = class'xT_SoundGroup_Human'

	BloodColor = (R=1.0,G=0,B=0,A=1.0)

	BloodEffects[0]=(Template=ParticleSystem'T_FX.Effects.P_FX_Bloodhit_Corrupt_Far',MinDistance=750.0)
	BloodEffects[1]=(Template=ParticleSystem'T_FX.Effects.P_FX_Bloodhit_Corrupt_Mid',MinDistance=350.0)
	BloodEffects[2]=(Template=ParticleSystem'T_FX.Effects.P_FX_Bloodhit_Corrupt_Near',MinDistance=0.0)

	BloodSplatterDecalMaterial = MaterialInstanceTimeVarying'T_FX.DecalMaterials.MITV_FX_OilDecal_Small01'
	BloodPoolDecalMaterial = DecalMaterial'xT_Decals.Materials.FX_Blood_Decal_Large'

	HeadShotEffect=ParticleSystem'T_FX.Effects.P_FX_HeadShot_Corrupt'

	GibExplosionTemplate=ParticleSystem'T_FX.Effects.P_FX_GibExplode_Corrupt'

	HeadGib=(BoneName=b_Head,GibClass=class'xFX_Gib_RobotHead',bHighDetailOnly=false)

	Gibs[0]=(BoneName=b_LeftForeArm,GibClass=class'xFX_Gib_RobotArm',bHighDetailOnly=false)
	Gibs[1]=(BoneName=b_RightForeArm,GibClass=class'xFX_Gib_RobotHand',bHighDetailOnly=true)
	Gibs[2]=(BoneName=b_LeftLeg,GibClass=class'xFX_Gib_RobotLeg',bHighDetailOnly=false)
	Gibs[3]=(BoneName=b_RightLeg,GibClass=class'xFX_Gib_RobotLeg',bHighDetailOnly=false)
	Gibs[4]=(BoneName=b_Spine,GibClass=class'xFX_Gib_RobotTorso',bHighDetailOnly=false)
	Gibs[5]=(BoneName=b_Spine1,GibClass=class'xFX_Gib_RobotChunk',bHighDetailOnly=true)
	Gibs[6]=(BoneName=b_Spine2,GibClass=class'xFX_Gib_RobotChunk',bHighDetailOnly=true)
	Gibs[7]=(BoneName=b_LeftClav,GibClass=class'xFX_Gib_RobotChunk',bHighDetailOnly=true)
	Gibs[8]=(BoneName=b_RightClav,GibClass=class'xFX_Gib_RobotArm',bHighDetailOnly=true)

	//DeathMeshSkelMesh = 
	//DeathMeshPhysAsset = 
	//SkeletonBurnOutMaterials[0] = 

	bCanCrouch=true

	Name="Default__xT_Pawn_Human"
}